//
//  BleManage.m
//  ZZBlue
//
//  Created by stonesMonkey on 2017/10/1.
//  Copyright © 2017年 stonesMonkey. All rights reserved.
//

#import "BleManage.h"
#import "Timerobj.h"
@interface BleManageInfo : NSObject{
    
}

@property (retain) CBPeripheral *peripheral;
@property (retain) CBCharacteristic *rxCharacteristic;
@property (retain) CBCharacteristic *txCharacteristic;
@property (retain) NSData *byte;
@property (nonatomic) int sendindex;
@end
@implementation BleManageInfo : NSObject {
    
}
@synthesize peripheral;
@synthesize rxCharacteristic;
@synthesize txCharacteristic;
@synthesize byte;
@synthesize sendindex;
@end

@interface BleManage () {
    CBCentralManager *cm;
    NSMutableArray *Peripherals;
    BOOL issendover;
}

@end

@implementation BleManage

@synthesize delegate;
@synthesize LEDANum;
@synthesize LEDBNum;
extern  Timerobj *timermange;

- (instancetype)init
{
    self = [super init];
    if (self) {
        cm = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
        Peripherals=[[NSMutableArray alloc]init];
    }
    return self;
}

+ (CBUUID *) uartServiceUUID
{
    return [CBUUID UUIDWithString:@"6e400001-b5a3-f393-e0a9-e50e24dcca9e"];
}

+ (CBUUID *) txCharacteristicUUID
{
    return [CBUUID UUIDWithString:@"6e400002-b5a3-f393-e0a9-e50e24dcca9e"];
}

+ (CBUUID *) rxCharacteristicUUID
{
    return [CBUUID UUIDWithString:@"6e400003-b5a3-f393-e0a9-e50e24dcca9e"];
}

+ (CBUUID *) deviceInformationServiceUUID
{
    return [CBUUID UUIDWithString:@"180A"];
}

+ (CBUUID *) hardwareRevisionStringUUID
{
    return [CBUUID UUIDWithString:@"2A27"];
}
- (void) centralManagerDidUpdateState:(CBCentralManager *)central
{
    if (delegate!=nil) {
        [delegate centralManagerDidUpdateState:central];
    }
    
}




-(void)startscan{
    [cm scanForPeripheralsWithServices:@[BleManage.uartServiceUUID] options:@{CBCentralManagerScanOptionAllowDuplicatesKey: [NSNumber numberWithBool:NO]}];
}
-(void)stopscan{
    [cm stopScan];
}
-(void)connectBle:(NSInteger)index{
    if (index<Peripherals.count) {
        BleManageInfo *bleManageInfo=Peripherals[index];
        [cm connectPeripheral:bleManageInfo.peripheral options:@{CBConnectPeripheralOptionNotifyOnDisconnectionKey: [NSNumber numberWithBool:YES]}];
    }
}

-(BOOL)getisconnect:(NSInteger)index{
    if (index<Peripherals.count) {
        BleManageInfo *bleManageInfo=Peripherals[index];
        if(bleManageInfo.peripheral.state==CBPeripheralStateConnected){
            return true;
        }else return false;
    }else return false;
    return false;
}



- (void) centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
    NSLog(@"%@ rssi=%d UUID=%@", peripheral.name,[RSSI intValue],peripheral.identifier.UUIDString);//搜索
    if ([peripheral.name isEqual:@"KURYAKYN"]) {
        BleManageInfo *bleManageInfo=[BleManageInfo alloc];
        bleManageInfo.peripheral=peripheral;
        [Peripherals addObject:bleManageInfo];
        peripheral.delegate = self;
        if (delegate!=nil) {
            [delegate UpDevNum:Peripherals.count];
        }
        
    }
}

- (void) centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
    NSLog(@"连接%@成功", peripheral.identifier.UUIDString);//连接成功
    [peripheral discoverServices:@[self.class.uartServiceUUID, self.class.deviceInformationServiceUUID]];
}

- (void) centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
    NSLog(@"%@已断开", peripheral.identifier.UUIDString);// 空闲(断开连接)
    for (BleManageInfo *bleManageInfo in Peripherals) {
        if ([bleManageInfo.peripheral isEqual:peripheral]) {
            [Peripherals removeObject:bleManageInfo];
        }
    }
    if (delegate!=nil) {
        [delegate UpDevNum:Peripherals.count];
    }
}
- (void) peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
    
    if (error)
    {
        NSLog(@"Error discovering services: %@", error);
        return;
    }
    
    for (CBService *s in [peripheral services])
    {
        if ([s.UUID isEqual:self.class.uartServiceUUID])
        {
            NSLog(@"Found correct service");
            
            [peripheral discoverCharacteristics:@[self.class.txCharacteristicUUID, self.class.rxCharacteristicUUID] forService:s];
        }
        else if ([s.UUID isEqual:self.class.deviceInformationServiceUUID])
        {
            [peripheral discoverCharacteristics:@[self.class.hardwareRevisionStringUUID] forService:s];
        }
    }
}




- (void) peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
    if (error)
    {
        NSLog(@"Error discovering characteristics: %@", error);
        return;
    }
    
    for (CBCharacteristic *c in [service characteristics])
    {
        if ([c.UUID isEqual:self.class.rxCharacteristicUUID])
        {
            NSLog(@"Found RX characteristic");
            for (BleManageInfo *bleManageInfo in Peripherals) {
                if ([bleManageInfo.peripheral isEqual:peripheral]) {
                    bleManageInfo.rxCharacteristic=c;
                    [peripheral setNotifyValue:YES forCharacteristic:c];
                    break;
                }
            }
        }
        else if ([c.UUID isEqual:self.class.txCharacteristicUUID])
        {
            NSLog(@"Found TX characteristic");
            for (BleManageInfo *bleManageInfo in Peripherals) {
                if ([bleManageInfo.peripheral isEqual:peripheral]) {
                    bleManageInfo.txCharacteristic=c;
                    
                    break;
                }
            }
            for (int i=0; i<Peripherals.count; i++) {
                BleManageInfo *bleManageInfo=Peripherals[i];
                if ([bleManageInfo.peripheral isEqual:peripheral]) {
                    if (delegate!=nil) {
                        [delegate connectSuccess:i];
                    }
                    break;
                }
            }
        }
        else if ([c.UUID isEqual:self.class.hardwareRevisionStringUUID])
        {
            NSLog(@"Found Hardware Revision String characteristic");
            [peripheral readValueForCharacteristic:c];
        }
    }
}


- (void) peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
    if (error)
    {
        NSLog(@"Error receiving notification for characteristic %@: %@", characteristic, error);
        return;
    }
    
    NSLog(@"Received data on a characteristic.");
    for (BleManageInfo *bleManageInfo in Peripherals) {
        if ([bleManageInfo.peripheral isEqual:peripheral]) {
            if (characteristic == bleManageInfo.rxCharacteristic)
            {
                
                [self sendlog:[characteristic value] hear:@"RCV"];
                for (int i=0; i<Peripherals.count; i++) {
                    BleManageInfo *bleManageInfo=Peripherals[i];
                    if ([bleManageInfo.peripheral isEqual:peripheral]) {
                        if (delegate!=nil) {
                            [delegate Blercvdata:[characteristic value] index:i];
                        }
                        break;
                    }
                }
                
            }
            else if ([characteristic.UUID isEqual:self.class.hardwareRevisionStringUUID])
            {
                //                NSString *hwRevision = @"";
                //                const uint8_t *bytes = characteristic.value.bytes;
                //                for (int i = 0; i < characteristic.value.length; i++)
                //                {
                //                    NSLog(@"%x", bytes[i]);
                //                    hwRevision = [hwRevision stringByAppendingFormat:@"0x%02x, ", bytes[i]];
                //                }
                //
                //                [self.delegate didReadHardwareRevisionString:[hwRevision substringToIndex:hwRevision.length-2]];
            }
            break;
        }
    }
    
    
}
- (BOOL) writeByte:(NSData *) byte index:(int)index time:(int)timevalue
{
    if (!issendover) {
        issendover=true;
        if (index<Peripherals.count) {
            [timermange myTimerStart:Ble_send_timer_id timevalue:timevalue+1 myFuncPtr:blesenddata value:0 objclass:self];
            BleManageInfo *bleManageInfo=Peripherals[index];
            bleManageInfo.byte=byte;
            bleManageInfo.sendindex=0;
        }
        return true;
    }else return false;
    
    return false;
}

void blesenddata(int value,id objclass){
    [objclass mainblesenddata:value];
}



-(void)mainblesenddata:(int)value{//在主线程里发送
    
    for (BleManageInfo *bleManageInfo in Peripherals) {
        if (bleManageInfo.byte!=nil) {
            NSData *byte ;
            const int maxlen=18;//最多每次发送maxlen字节
            if (bleManageInfo.sendindex==0) {
                unsigned char buf[20];
                if (bleManageInfo.byte.length<=maxlen+1) {
                    unsigned char *ptr=(unsigned char *)bleManageInfo.byte.bytes;
                    buf[0]=4;
                    for (int i=0;i<bleManageInfo.byte.length; i++) {
                        buf[i+1]=*(ptr+i);
                    }
                    byte = [NSData dataWithBytes: buf length:bleManageInfo.byte.length+1];
                    bleManageInfo.byte=nil;
                    bleManageInfo.sendindex=0;
                }else{
                    buf[0]=1;
                    byte = [NSData dataWithBytes: buf length:1];
                    bleManageInfo.sendindex++;
                }
                
            }else if ((bleManageInfo.sendindex-1)*maxlen<bleManageInfo.byte.length) {//每次最多只能传20个字节
                unsigned char buf[20];
                int j=2;
                unsigned char *ptr=(unsigned char *)bleManageInfo.byte.bytes;
                buf[0]=2;
                buf[1]=bleManageInfo.sendindex;
                for (int i=(bleManageInfo.sendindex-1)*maxlen;(i-(bleManageInfo.sendindex-1)*maxlen<maxlen)&&i<bleManageInfo.byte.length; i++) {
                    buf[j++]=*(ptr+i);
                }
                byte = [NSData dataWithBytes: buf length:j];
                bleManageInfo.sendindex++;
            }else {
                unsigned char buf[20];
                buf[0]=3;
                byte = [NSData dataWithBytes: buf length:1];
                bleManageInfo.byte=nil;
                bleManageInfo.sendindex=0;
            }
            [self sendlog:byte hear:@"send"];
            if ((bleManageInfo.txCharacteristic.properties & CBCharacteristicPropertyWriteWithoutResponse) != 0)
            {
                [bleManageInfo.peripheral writeValue:byte forCharacteristic:bleManageInfo.txCharacteristic type:CBCharacteristicWriteWithoutResponse];
            }
            else if ((bleManageInfo.txCharacteristic.properties & CBCharacteristicPropertyWrite) != 0)
            {
                [bleManageInfo.peripheral writeValue:byte forCharacteristic:bleManageInfo.txCharacteristic type:CBCharacteristicWriteWithResponse];
            }
            else
            {
                NSLog(@"No write ");
            }
            [timermange myTimerStart:Ble_send_timer_id timevalue:1 myFuncPtr:blesenddata value:0 objclass:self];
        }else {
            issendover=false;
            if (delegate!=nil) {
                [delegate BleSendOver];
            }
        }
    }
}

-(void)sendlog:(NSData*)byte hear:(NSString*)hear{
    NSString *str=@"";
    unsigned char *ptr=(unsigned char *)byte.bytes;
    for (int i=0;i<byte.length;i++) {
        str=[NSString stringWithFormat:@"%@ %02X",str,*(ptr+i)];
    }
    NSLog(@"%@:%@",hear,str);
}























@end

